﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ReadOnlyList.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the ReadOnlyList type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Collections
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public struct ReadOnlyList<T> : IList<T>, IList
    {
        #region Fields

        private readonly T[] _list;

        #endregion

        public ReadOnlyList(T[] list)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }
            _list = list;
        }

        public static readonly ReadOnlyList<T> Empty = new ReadOnlyList<T>(EmptyArray<T>.Instance);

        private IList List
        {
            get { return _list; }
        }

        private IList<T> TypedList
        {
            get { return _list; }
        }

        #region IList Members

        int IList.Add(object value)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        bool IList.Contains(object value)
        {
            return List.Contains(value);
        }

        void IList.Clear()
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        int IList.IndexOf(object value)
        {
            return List.IndexOf(value);
        }

        void IList.Insert(int index, object value)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        void IList.Remove(object value)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        void IList.RemoveAt(int index)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        object IList.this[int index]
        {
            get { return this[index]; }
            set { throw CollectionExceptions.CollectionIsReadOnly(); }
        }

        public bool IsFixedSize
        {
            get { return true; }
        }

        void ICollection.CopyTo(Array array, int index)
        {
            List.CopyTo(array, index);
        }

        object ICollection.SyncRoot
        {
            get { return List.SyncRoot; }
        }

        public bool IsSynchronized
        {
            get { return false; }
        }

        #endregion

        #region IList<TMessage> Members

        public IEnumerator<T> GetEnumerator()
        {
            return TypedList.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        void ICollection<T>.Add(T item)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        void ICollection<T>.Clear()
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        void IList<T>.RemoveAt(int index)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        public bool Contains(T item)
        {
            return TypedList.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            TypedList.CopyTo(array, arrayIndex);
        }

        bool ICollection<T>.Remove(T item)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        public int Count
        {
            get { return TypedList.Count; }
        }

        public int IndexOf(T item)
        {
            return TypedList.IndexOf(item);
        }

        void IList<T>.Insert(int index, T item)
        {
            throw CollectionExceptions.CollectionIsReadOnly();
        }

        public T this[int index]
        {
            get { return TypedList[index]; }
            set { throw CollectionExceptions.CollectionIsReadOnly(); }
        }

        #endregion
    }
}